﻿/*   
    Copyright (C) 2009 Galaktika Corporation ZAO

    This file is a part of Galaktika.BusinessMonitor
 
    Galaktika.BusinessMonitor is a free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
      
    You should have received a copy of the GNU General Public License
    along with Galaktika.BusinessMonitor.  If not, see <http://www.gnu.org/licenses/>.
  
    If GPL v.3 is not suitable for your products or company,
    Galaktika Corp provides Galaktika.BusinessMonitor under a flexible commercial license
    designed to meet your specific usage and distribution requirements.
    If you have already obtained a commercial license from Galaktika Corp,
    you can use this file under those license terms.
*/

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Browser;
using System.Collections.Generic;
using System.Windows.Controls.Primitives;
using System.Globalization;

namespace Galaktika.BI.Silverlight.Controls
{
    public partial class HtmlHostControl : UserControl
    {
        private bool isWindowLess;
        private HtmlElement hostedElement;
        private string uniqueName;
        private Size lastMeasure;
         
        public HtmlHostControl()
        {
            this.uniqueName = Guid.NewGuid().ToString();
            this.SourceHtml = string.Empty;
        }
           
        public string SourceHtml { get; set; }
        public bool FrameBorder { get; set; }

        public void ShowHtmlBySource(string parsedHtml)        
        {
            if (HtmlPage.IsEnabled)
            {
                this.isWindowLess = Application.Current.Host.Settings.Windowless;
                if (this.isWindowLess)
                {
                    HtmlDocument doc = HtmlPage.Document;
                    hostedElement = doc.CreateElement("div");
                    hostedElement.SetStyleAttribute("position", "absolute");
                    hostedElement.SetAttribute("id", System.Guid.NewGuid().ToString());
                    hostedElement.SetStyleAttribute("height", "0px");
                    hostedElement.SetStyleAttribute("width", "0px");
                    hostedElement.SetStyleAttribute("left", "0px");
                    hostedElement.SetStyleAttribute("top", "0px");
                    hostedElement.SetStyleAttribute("z-index", "1");
                    this.hostedElement.SetStyleAttribute("overflow", "auto");
                    this.SourceHtml = parsedHtml;
                    this.LayoutUpdated += new EventHandler(HtmlHostControl_LayoutUpdated);
                    this.UpdateInnerHtml(null);
                }
            }
        }

        public void ShowHtmlByUri(Uri uri)
        {
            if (HtmlPage.IsEnabled)
            {
                this.isWindowLess = Application.Current.Host.Settings.Windowless;
                if (this.isWindowLess)
                {
                    HtmlDocument doc = HtmlPage.Document;
                    hostedElement = doc.CreateElement("div");
                    hostedElement.SetStyleAttribute("position", "absolute");
                    hostedElement.SetAttribute("id", System.Guid.NewGuid().ToString());
                    hostedElement.SetStyleAttribute("height", "0px");
                    hostedElement.SetStyleAttribute("width", "0px");
                    hostedElement.SetStyleAttribute("left", "0px");
                    hostedElement.SetStyleAttribute("top", "0px");
                    hostedElement.SetStyleAttribute("z-index", "1");
                    this.hostedElement.SetStyleAttribute("overflow", "auto");
                    
                    System.Windows.Browser.HtmlElement myFrame = System.Windows.Browser.HtmlPage.Document.GetElementById("ifHtmlContent");
                    if (myFrame != null)
                        myFrame.SetAttribute("src", uri.OriginalString);
                    this.LayoutUpdated += new EventHandler(HtmlHostControl_LayoutUpdated);
                    this.UpdateInnerHtml(uri);
                }
            }
        }

        private void UpdateInnerHtml(Uri uri)
        {
            if (HtmlPage.IsEnabled)
            {
                if (this.hostedElement != null)
                {
                    if (uri != null)
                    {
                         this.hostedElement.SetProperty("innerHTML", string.Format(CultureInfo.InvariantCulture, "<iframe width=\"100%\" height=\"100%\" src=\"{0}\" frameborder=\"{2}\"/>", new object[] { uri.OriginalString, this.uniqueName, this.FrameBorder ? "1" : "0" }));
                    }
                    else
                    {
                        this.hostedElement.SetProperty("innerHTML", string.Format(CultureInfo.InvariantCulture, "<div>{0}</div>", new object[] { this.SourceHtml }));
                    }
                    base.InvalidateMeasure();
                }
            }           
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
        }

        void HtmlHostControl_LayoutUpdated(object sender, EventArgs e)
        {
            this.OnLayoutUpdated();
        }

        private void OnLayoutUpdated()
        {
            Point silverlightLocation = DomUtil.GetLocation(HtmlPage.Plugin);
            Point location = new Point(0.0, 0.0);
            IList<FrameworkElement> allParents = this.GetAllParents();
            FrameworkElement root = this.GetRoot();
            bool flag = (base.Visibility == Visibility.Visible);
            bool flag2 = Extensions.IsInVisualTree(this) || ((root is Popup) && (root as Popup).IsOpen);
            if (flag && flag2)
            {
                try
                {
                    location = this.TransformToVisual(Application.Current.RootVisual).Transform(new Point(0.0, 0.0));
                }
                catch (ArgumentException)
                {
                    flag2 = flag = false;
                }
            }
            if (flag && flag2)
            {
                Rect accumulatedClip = this.GetAccumulatedClip(location);
                //this.hostedElement.SetStyleAttribute("clip", string.Format(CultureInfo.InvariantCulture, "rect({0}px {1}px {2}px {3}px)", new object[] { (int)Math.Ceiling(accumulatedClip.Y), (int)accumulatedClip.Width, (int)accumulatedClip.Height, (int)Math.Ceiling(accumulatedClip.X) }));
                this.hostedElement.SetStyleAttribute("left", ((int)(silverlightLocation.X + location.X)) + "px");
                this.hostedElement.SetStyleAttribute("top", ((int)(silverlightLocation.Y + location.Y)) + "px");
                this.hostedElement.SetStyleAttribute("width", ((int)Math.Ceiling(accumulatedClip.Width)) + "px");
                this.hostedElement.SetStyleAttribute("height", ((int)Math.Ceiling(accumulatedClip.Height)) + "px");            
                HtmlPage.Document.Body.AppendChild(this.hostedElement);
            }
            else if (!flag2)
            {
                HtmlPage.Document.Body.RemoveChild(this.hostedElement);
            }
            this.hostedElement.SetStyleAttribute("display", flag ? "block" : "none");
            //this.hostedElement.SetProperty("scrollTop", 0);
            //this.hostedElement.SetProperty("scrollLeft", 0);
            //HtmlElement property = (HtmlElement)this.hostedElement.GetProperty("firstChild");
            //property.SetStyleAttribute("width", ((int)Math.Ceiling(base.ActualWidth)) + "px");
            //property.SetStyleAttribute("height", ((int)Math.Ceiling(base.ActualHeight)) + "px");
        }

        protected override Size MeasureOverride(Size availableSize)
        {
            if ((HtmlPage.IsEnabled && !string.IsNullOrEmpty(this.SourceHtml)) && this.isWindowLess)
            {
                Size size = DomUtil.Measure((this.hostedElement.Children.Count == 1) ? this.hostedElement : this.hostedElement, availableSize.Width);
                return (this.lastMeasure = new Size(Math.Min(double.IsNaN(base.Width) ? size.Width : base.Width, availableSize.Width), Math.Min(double.IsNaN(base.Height) ? size.Height : base.Height, availableSize.Height)));
            }
            return (this.lastMeasure = new Size(double.IsInfinity(availableSize.Width) ? 300.0 : availableSize.Width, double.IsInfinity(availableSize.Height) ? 300.0 : availableSize.Height));
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            return this.lastMeasure;
        }

    }
}
